<?php
class WeixinApi {
    //获取公众号账户用户openid列表并返回对应的用户详细信息
    public static function getCustomerWxUserList($accessToken){
        //获取所有用户openid
        $url= "https://api.weixin.qq.com/cgi-bin/user/get?access_token=$accessToken&next_openid=";
        // 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $res= json_decode(curl_exec($ch));
        curl_close($ch);
        $total = $res ->total;
        $count = $res ->count;
        $openIds = $res->data->openid;
        $next_openid = $res->next_openid;
        $num  = $total<=10000 ? 0 : ceil($total/$count);

        for($i=0;$i< $num;$i++){
            $urlnext= "https://api.weixin.qq.com/cgi-bin/user/get?access_token=$accessToken&next_openid=$next_openid";
            $ch = curl_init($urlnext) ;
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
            $res= json_decode(curl_exec($ch));
            curl_close($ch);
            $next_openid = $res->next_openid;
            array_push($openIds,$res ->next_openid);
        }
        //所有通过接口拉取过来的用户详细信息
        $userArr = array();

        $redis = new Redis();
        $redis->connect(C('REDIS_HOST'), C('REDIS_PORT'));
        $redis->auth(C('REDIS_PASSWORD'));
        //删除队列
        $redis->delete($accessToken);
        //循环获取每个openid对应的用户详细信息
        foreach($openIds as $v){
            $url= "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$accessToken&openid=$v&lang=zh_CN";
            // 		Log::write($url);
            $ch = curl_init($url) ;
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
            $info= json_decode(curl_exec($ch));
            curl_close($ch);
            if($info !== null){
                //array_push($userArr,$info);之前数据量大,存本地数据库是内存过大导致失败,改为存redis
                /*jie改动时间2017-7-13*/
                $redis->lPush($accessToken, serialize($info));
            }
        }
        return $accessToken;
    }

    /**
     * 获取accesstoken
     *
     * @param bool $printErr
     * @param null $cid
     * @param null $from
     * @param int  $mediaId     自媒体平台id
     */
    public static function getAccessToken($printErr = TRUE, $cid = null, $from = null, $mediaId = 0)
    {
        $result = self::getCustomer($cid, $mediaId);
        if (!$result) {
            if ($printErr) {
                Output::instance()->resultCode(code_user_not_exist);
            }
            return;
        }

        if ($result['mode'] && $result['grantStatus']) {
            $token = self::getThirdAccessTokenByCustomer($result, $printErr, $mediaId);
        } else {
            $token = self::getAccessTokenByCustomer($result, $printErr, $from, $mediaId);
        }
        return $token;
    }

    /*jssdk调用相关开始*/
    //获取jssdk签名
    public static function getSignPackage($url=null) {
        $customer = self::getCustomer();
        $appId = $customer["appid"];
        $appsecret = $customer["appsecret"];
        $jsapiTicket = self::getJsApiTicket();
        $SERVER_NAME=self::getDomainName($customer);
        $SERVER_NAME = $SERVER_NAME['SERVER_NAME'];
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        //孟慧更改
        if ($url){
            $url = $url;
        }else{
            $url = "$SERVER_NAME$_SERVER[REQUEST_URI]";
        }

        $timestamp = time();
        $nonceStr = self::createNonceStr();
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        $signature = sha1($string);
        $signPackage = array(
          "appId"     => $appId,
          "nonceStr"  => $nonceStr,
          "timestamp" => $timestamp,
          "url"       => $url,
          "signature" => $signature,
          "rawString" => $string
        );
        return $signPackage;
      }
//	  public  static function getjsApiAccessToken() {
//	    // access_token 应该全局存储与更新，以下代码以写入到文件中做示例
//	    $data = unserialize(file_get_contents(__DIR__ . "/access_token.json"));
//	    $customer = self::getCustomer();
//		$appId = $customer["appid"];
//		$appsecret = $customer["appsecret"];
//		$customerId=$customer["id"];
//		$obj=$data[$customerId];
//		if ($obj->expire_time < time()) {
//	      $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appId&secret=$appsecret";
//	      $res = json_decode(self::httpGet($url));
//	      $access_token = $res->access_token;
//	      if ($access_token) {
//	        $obj=new stdClass();
//	        $obj->expire_time=time() + 7000;
//	        $obj->access_token = $access_token;
//	        $data[$customerId]=$obj;
//	        $fp = fopen(__DIR__ ."/access_token.json", "w");
//	        fwrite($fp, serialize($data));
//	        fclose($fp);
//	      }
//	    } else {
//	      $access_token = $obj->access_token;
//	    }
//	    return $access_token;
//	  }

        //为获取签名而写
    public static function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
          $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    public static function getJsApiTicket() {
        $data = unserialize(file_get_contents(__DIR__ . "/jsapi_ticket.json"));
        $customer = self::getCustomer();
        $customerId=$customer["id"];
        $obj=$data[$customerId];
        if ($obj->expire_time < time()) {
          $accessToken = self::getAccessToken();
          // 如果是企业号用以下 URL 获取 ticket
          // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
          $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
          $res = json_decode(self::httpGet($url));
          $ticket = $res->ticket;
          if ($ticket) {
            $obj=new stdClass();
            $obj->expire_time=time() + 7000;
            $obj->jsapi_ticket = $ticket;
            $data[$customerId]=$obj;
            $fp = fopen(__DIR__ . "/jsapi_ticket.json", "w");
            fwrite($fp, serialize($data));
            fclose($fp);
          }
        } else {
          $ticket = $obj->jsapi_ticket;
        }
        return $ticket;
    }
    public static function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }
	/*jsskd调用相关结束*/
	public static function getCustomerAndAccessToken(){
		$result = self::getCustomer();
		if (!$result) {
			Output::instance()->resultCode(code_user_not_exist);
			return;
		}
		
		$token = self::getAccessTokenByCustomer($result);
		if (isset($token)) {
			$result['token'] = $token;
			return $result;
		} else {
			return;
		}
	}

    /**
     * 获得第三方平台accesstoken
     *
     * @param      $result      wx_customer信息 - 该多自媒体账号后, 信息来自ind_media_info, [参考self::getCustomer](很神奇的参数名)
     * @param bool $printErr    结果是否输出到页面, true-输出
     */
    private static function getThirdAccessTokenByCustomer($result, $printErr = TRUE, $mediaId = 0)
    {
        $third_platform_appid = $result['third_platform_appid'];
        $cid = Session::$user['customerId'];
        Session::switchCustomer(0);
        $thirdPlatform = M("third_platform");
        Session::switchCustomer($cid);
        $platformInfo = $thirdPlatform->where("appid='$third_platform_appid'")->find();
        $appid = $platformInfo['appid'];
        $token = $result['accessToken'];//echo $token;return ;
        $expiration = $result['accessExpiration'];
        $refreshToken = $result['refreshToken'];
        /**
         * if (isset($token) && isset($expiration)) {
         * 修改原因: 老后台 => 账户管理模块 => 用户点击"保存"按钮时, 会将用户的第三方的token清空, 导致获取不到token, 任何操作无法进行
         * @modify 小白龙 lilei<LL_strive@163.com> 2017-05-09
         */
        if (isset($refreshToken) && isset($expiration)) {
            if ($expiration > time()) {
                Log::write('getAccessToken in expiration');
                return $token;
            } else if ($refreshToken) {
                //刷新token
                $access = WechatThirdPlatform::refresh_access_token($appid, $result['appid'], $refreshToken);
                if (isset($access->authorizer_access_token)) {
                    $authorizer_access_token = $access->authorizer_access_token;
                    $expires_in = time() + ((int)$access->expires_in - 60);
                    $authorizer_refresh_token = $access->authorizer_refresh_token;
                    self::setCustomerToken($authorizer_access_token, $expires_in, $authorizer_refresh_token, null, $mediaId);
                }
                if ($authorizer_access_token) {
                    return $authorizer_access_token;
                } else {
                    if ($printErr) {
                        if($mediaId){
                            return code_userinfo_notset;
                        }
                        Output::instance()->resultCode(code_userinfo_notset);
                    }
                    return;
                }
            }
        }
        if ($printErr) {
            Output::instance()->resultCode(code_userinfo_notset);
        }
        return;
    }

    /**
     * 获取AccessToken
     *
     * @param      $result      wx_customer信息 - 该多自媒体账号后, 信息来自ind_media_info, [参考self::getCustomer](很神奇的参数名)
     * @param bool $printErr    结果是否输出到页面, true-输出
     * @param null $from        ? 这个应该是微信小程序的东西
     */
    private static function getAccessTokenByCustomer($result, $printErr = TRUE, $from = null, $mediaId = 0)
    {
        if ($from) {
            $token = $result['wxAppAccessToken'];//echo $token;return ;
            $expiration = $result['wxAppAccessExpiration'];
            $appid = $result['wxAppAppid'];
            $secret = $result['wxAppSecret'];
        } else {
            $token = $result['accessToken'];//echo $token;return ;
            $expiration = $result['accessExpiration'];
            $appid = $result['appid'];
            $secret = $result['appsecret'];
        }
        if (isset($token) && isset($expiration)) {
            if ($expiration > time()) {
                Log::write('getAccessToken in expiration');
                return $token;
            }
        }
        if (!isset($appid) || !isset($secret)) {
            if ($printErr) {
                Output::instance()->resultCode(code_userinfo_notset);
            }
            return;
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret;
// 		Log::write($url);
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $access = curl_exec($ch);
        curl_close($ch);
        Log::write("token result  ".$access);
        $access = json_decode($access);
        if (isset($access->access_token)) {
            $token = $access->access_token;
            // 过期时间减去一分钟
            $expiration = time() + ((int)$access->expires_in - 60);
            self::setCustomerToken($token, $expiration, null, $from, $mediaId);
            return $token;
        } else {
            if ($printErr) {
                Output::instance()->resultCode(code_access_expired, NULL, $access->errcode);
            }
            return;
        }
    }

    public static function getDomainName($customer=null){
        if(!$customer){
            $customer = self::getCustomer();
        }
        if($customer['mode']&&$customer['grantStatus']){
            $domainName = $customer["appid"];
            $result['SERVER_HOST']="http://".$domainName.".".C('NEWSERVER_HOST');
            $result['SERVER_NAME']="http://".$domainName.".".C('NEWSERVER_NAME');
            $result['RESOURCEURL']="http://".$domainName.".".C('NEWRESOURCEURL');
        }else{
            $result['SERVER_NAME'] = C("SERVER_NAME");
            $result['SERVER_HOST'] = C("SERVER_HOST");
            $result['RESOURCEURL'] = C("RESOURCEURL");
        }
        return $result;
    }
    public static function getOauthAccessToken($scope,$srcUrl=null) {
        log::write("menghuidayiin在WeixinApi中.code".$_GET['code']);
        $customer = self::getCustomer();
        if($customer['mode']&&$customer['grantStatus']){
            $access= WechatThirdPlatform::getOauthAccessToken($customer,$scope,$srcUrl);
            return $access;
        }

        $appid = $customer["appid"];
        $appsecret = $customer["appsecret"];
        $isApiAuth = $customer["isApiAuth"];
        if ($isApiAuth == false) {
        // 避免菜单跳转时显示错误
        //	Output::instance()->resultCode(code_userinfo_api_auth_not_set);
            return;
        }
        if (!isset($appid) || !isset($appsecret)) {
            //Output::instance()->resultCode(code_userinfo_notset);
            return;
        }
        $code = $_GET['code'];
        $SERVER_NAME=self::getDomainName($customer);
        $SERVER_NAME = $SERVER_NAME['SERVER_NAME'];
        $REQUEST_URI=$_SERVER['REQUEST_URI'];

        if (isset($code)) {
            $access = self::getOauthByCode($appid, $appsecret, $code);
            if ($access && !$access->errcode) {
                return $access;
            } else { //code错误重新获取
                if ($srcUrl){
                    $redirectUrl = $srcUrl;
                }else{
                    $redirectUrl = urlencode($SERVER_NAME .  preg_replace("/&code=\w+/","",$REQUEST_URI));
                }

                Log::write('redirect1 is ' . $redirectUrl);
                $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirectUrl&response_type=code&scope=$scope&state=STATE#wechat_redirect";
                //如果有传入的跳转url项
                if ($srcUrl){
                    $return['code'] = 0;
                    $return['msg'] = $url;
                    Output::instance()->object($return);
                    die;
                }else{
                     redirect($url);
                }

            }
        } else {
            if ($srcUrl){
                $redirectUrl = $srcUrl;
            }else{
                $redirectUrl = urlencode($SERVER_NAME .  $REQUEST_URI);
            }

            $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirectUrl&response_type=code&scope=$scope&state=STATE#wechat_redirect";
            Log::write('redirect&url is ' . $url);
            if ($srcUrl){
                $return['code'] = 0;
                $return['msg'] = $url;
                Output::instance()->object($return);
                die;
            }else{
                 redirect($url);
            }
        }
    }
    public static function getUserOauthAccessToken($fromUserName) {
        $user = self::getUser($fromUserName);
        if (!$user) {
            Output::instance()->resultCode(code_user_not_exist);
            return;
        }
        $accessToken = $user['oauthAccessToken'];
        $expiration = $user['oauthAccessExpiration'];
        if (isset($accessToken) && isset($expiration)) {
            if ($expiration > time()) {
                return $accessToken;
            }
        }
        Output::instance()->resultCode(code_userinfo_api_auth_invalid);
        return;
    }
    private static function getOauthAccessTokenByRefreshToken($fromUserName) {
        $customer = self::getCustomer();
        $appid = $customer["appid"];
        $appsecret = $customer["appsecret"];
        $isApiAuth = $customer["isApiAuth"];
        if ($isApiAuth == false) {
// 	 		Output::instance()->resultCode(code_userinfo_api_auth_not_set);
            return;
        }
        if (!isset($appid) || !isset($appsecret)) {
// 	 		Output::instance()->resultCode(code_userinfo_notset);
            return;
        }
        $user = self::getUser($fromUserName);
        if (!$user) {
// 	 		Output::instance()->resultCode(code_user_not_exist);
            return;
        }
        $token = $user['oauthAccessToken'];
        $expiration = $user['oauthAccessExpiration'];
        if (isset($token) && isset($expiration)) {
            if ($expiration > time()) {
                $access = self::getOauthByRefreshToken($appid, $user['oauthRefreshToken']);
                if ($access) {
                    return $access;
                }
            } else {
                $access = new stdClass();
                $access->openid = $fromUserName;
                $access->access_token = $token;
                return $access;
            }
        }
//  	Output::instance()->resultCode(code_userinfo_api_auth_invalid);
        return;
    }
    public static function getOauthCodeAndState() {
        $access = self::getOauthAccessToken(SNSAPI_BASE);
        $SERVER_NAME=self::getDomainName();
        $SERVER_NAME = $SERVER_NAME['SERVER_NAME'];
        if (!$access) {
            $requestUrl = $SERVER_NAME . $_SERVER['REQUEST_URI'];
            Log::write('auth failed:' . $requestUrl);
            return;
        }
        $redirectUrl = $SERVER_NAME .  $_SERVER['REQUEST_URI'];
        redirect($redirectUrl);
    }
    public static  function getOauthUserInfo($access) {
        $fromUserName = Session::$user["userName"];
        if (empty($fromUserName)) {
            Log::write("getOauthUserInfo user empty");
            return;
        }
        $accessToken = $access->access_token;
        $openId = $access->openid;
        $url= "https://api.weixin.qq.com/sns/userinfo?access_token=$accessToken&openid=$openId&lang=zh_CN";
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $userInfo = curl_exec($ch) ;
        curl_close($ch);
        $userInfo = json_decode($userInfo);
        if (isset($userInfo->errcode) && $userInfo->errcode != 0) {
            Log::write('oauth user info error:' . $userInfo->errmsg);
            // 			Output::instance()->resultCode(code_userinfo_api_auth, $userInfo->errmsg);
            return;
        }
        return $userInfo;
    }
    public static function isSetUserAppId() {
        $result = self::getCustomer();
        $appid = $result['appid'];
        $secret = $result['appsecret'];
        if (!isset($appid) || !isset($secret)) {
            Output::instance()->resultCode(code_userinfo_notset);
            return false;
        } else {
            return true;
        }
    }

    /**
     * 新生成菜单
     *
     * @param     $menu
     * @param int $mediaId
     * @return bool
     */
    public static function createMenu($menu, $mediaId = 0)
    {
        $access_token = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $access_token;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $menu);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        // 		Log::write($result);
        curl_close($ch);
        $result = json_decode($result);
        if ($result->errcode === 0) {
// 			Output::instance()->resultCode(code_success);
            return true;
        } else {
            Log::write('create menu error code:' . $result->errcode . ';msg:' . $result->errmsg);
            Log::write('menu:' . $menu);
            Output::instance()->resultCode(code_menu_create);
            return false;
        }
    }

    /**
     * 删除菜单
     *
     * @param int $mediaId
     * @return bool
     */
    public static function deleteMenu($mediaId = 0)
    {
        $access_token = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $post_data = array();
        $post_data['access_token'] = $access_token;
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/delete';
        $o = "";
        foreach ($post_data as $k => $v) {
            $o .= "$k=" . urlencode($v) . "&";
        }
        $post_data = substr($o, 0, -1);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 0);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        curl_close($ch);
// 		Log::write($result);
        $result = json_decode($result);
        if ($result->errcode === 0) {
            return true;
        } else {
            Log::write('delete menu error code:' . $result->errcode . ';msg:' . $result->errmsg);
            Output::instance()->resultCode(code_menu_delete);
            return false;
        }
    }

    /**
     * 获得微信已设置的菜单
     *
     * @param int $mediaId
     * @return bool|mixed
     */
    public function getMenu($mediaId = 0) {
        $accessToken = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!$accessToken) {
            return false;
        }
        $getMenuUrl='https://api.weixin.qq.com/cgi-bin/menu/get?access_token='.$accessToken;
        $ch = curl_init($getMenuUrl) ;
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $val = curl_exec($ch) ;
        return $val;
    }
    public static function sendText($toUser, $content, $printErr = false) {
        $accessToken = WeixinApi::getAccessToken($printErr);
        if (!$accessToken) {
            return;
        }
        $result = WeixinApi::sendTextByToken($accessToken, $toUser, $content);
        if ($result->errcode === 0) {
            WeixinApi::saveTextMessage($toUser, $content);
            if ($printErr) {
                Output::instance()->resultCode();
                return true;
            } else {
                return $result;
            }
        } else {
            Log::write('send user msg fail:'. $result->errmsg);
            if ($printErr) {
                Output::instance()->resultCode(code_user_msg_send_fail, NULL, $result->errcode);
                return true;
            } else {
                return $result;
            }
        }
    }
    private static function saveTextMessage($toUserName, $content) {
        $cid = Session::$user["customerId"];
        $Message = D("Message");
        $Message->create();
        // 			$Message->fromUserName = '';
        $Message->toUserName = $toUserName;
        $Message->msgType = message_type_text;
        $Message->msgId = 0;
        $Message->customerId = $cid;
        $Message->msgMark = message_type_reply;
        $Message->createTime = date("Y-m-d H:i:s");
        $Message->content = $content;
        $result = $Message->add();
        if (!$result) {
            Log::write('Add Message Error:' . $Message->getError());
        }
    }
    /**
     * 发送消息到指定accessToken帐号
     * @param  $accessToken
     * @param  $toUser
     * @param  $content urlencode后的内容
     */
    public static function sendTextByToken($accessToken, $toUser, $content) {
        $msg["touser"] = $toUser;
        $msg["msgtype"] = message_type_text;
        $msgContent["content"] = urlencode($content);
        $msg["text"] = $msgContent;
        $msg = urldecode(json_encode($msg));
        $url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $accessToken;
// 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
// 		Log::write($result);
        $result = json_decode($result);
        return $result;
    }
    public static function sendImage($toUser, $mediaId, $printErr = false) {
        $accessToken = WeixinApi::getAccessToken($printErr);
        if (!$accessToken) {
            return;
        }
        $result = WeixinApi::sendImageByToken($accessToken, $toUser, $mediaId);
        if ($result->errcode === 0) {
            if ($printErr) {
                Output::instance()->resultCode();
                return true;
            } else {
                return $result;
            }
        } else {
            Log::write('send user msg fail:'. $result->errmsg);
            if ($printErr) {
                Output::instance()->resultCode(code_user_msg_send_fail, NULL, $result->errcode);
                return false;
            } else {
                return $result;
            }
        }
    }
    public static function sendImageByToken($accessToken, $toUser, $mediaId) {
        $msg["touser"] = $toUser;
        $msg["msgtype"] = message_type_image;
        $msgContent["media_id"] = $mediaId;
        $msg["image"] = $msgContent;
        // 		Log::write('news content' . json_encode($msg));
        $msg = urldecode(json_encode($msg));
        $url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $accessToken;
        // 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
        // 		Log::write($result);
        $result = json_decode($result);
        return $result;
    }
    public static function sendVoice($toUser, $mediaId, $printErr = false) {
        $accessToken = WeixinApi::getAccessToken($printErr);
        if (!$accessToken) {
            return;
        }
        $result = WeixinApi::sendVoiceByToken($accessToken, $toUser, $mediaId);
        if ($result->errcode === 0) {
            if ($printErr) {
                Output::instance()->resultCode();
                return true;
            } else {
                return $result;
            }
        } else {
            Log::write('send user msg fail:'. $result->errmsg);
            if ($printErr) {
                Output::instance()->resultCode(code_user_msg_send_fail, NULL, $result->errcode);
                return false;
            } else {
                return $result;
            }
        }
    }
    public static function sendVoiceByToken($accessToken, $toUser, $mediaId) {
        $msg["touser"] = $toUser;
        $msg["msgtype"] = message_type_voice;
        $msgContent["media_id"] = $mediaId;
        $msg["voice"] = $msgContent;
        // 		Log::write('news content' . json_encode($msg));
        $msg = urldecode(json_encode($msg));
        $url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $accessToken;
        // 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
        // 		Log::write($result);
        $result = json_decode($result);
        return $result;
    }
    public static function sendNews($toUser, $articles,$printErr = false) {
        $accessToken = WeixinApi::getAccessToken($printErr);
        if (!$accessToken) {
            return;
        }
        $result = WeixinApi::sendNewsByToken($accessToken, $toUser, $articles);
        if ($result->errcode === 0) {
            $newHtml=WeixinApi::newsToHtml($articles);
            WeixinApi::saveNewsMessage($toUser, $newHtml);
            if ($printErr) {
                Output::instance()->resultCode();
                return true;
            } else {
                return $result;
            }
        } else {
            Log::write('send user news fail:'. $result->errmsg);
            if ($printErr) {
                Output::instance()->resultCode(code_user_msg_send_fail, NULL, $result->errcode);
                return false;
            } else {
                return $result;
            }
        }
    }
    private static function saveNewsMessage($toUserName, $content) {
        $cid = Session::$user["customerId"];
        $Message = D("Message");
        $Message->create();
        // 			$Message->fromUserName = '';
        $Message->toUserName = $toUserName;
        $Message->msgType = 'news';
        $Message->msgId = 0;
        $Message->customerId = $cid;
        $Message->msgMark = message_type_reply;
        $Message->createTime = date("Y-m-d H:i:s");
        $Message->content = $content;
        $result = $Message->add();
        if (!$result) {
            Log::write('Add Message Error:' . $Message->getError());
        }
    }
    public static function newsToHtml($articles) {
        if(!$articles || count($articles) == 0) {
            return "";
        }
        // 参数为object/array都支持
        if (is_object($articles[0])) {
            $url1 = $articles[0]->url;
            $pic1 = $articles[0]->picUrl;
            $title1 = $articles[0]->title;
        } else {
            $url1 = $articles[0]['url'];
            $pic1 = $articles[0]['picurl'];
            $title1 = $articles[0]['title'];
        }
        $html='<div class="materialView multiView">';
        $html.='<div class="item">';
        $html.='<div class="pic">';
        $html.='<a href="'.urldecode($url1).'" target="_blank"><img src="'.urldecode($pic1).'" /></a>';
        $html.=' <div class="title">';
        $html.='<a href="'.urldecode($url1).'" target="_blank">'.urldecode($title1).'</a>';
        $html.='</div>';
        $html.='</div>';
        $html.='</div>';
        $html.='<ul class="list">';
        for ($i = 1; $i < count($articles).length; $i++) {
            if (is_object($articles[$i])) {
                $url = $articles[$i]->url;
                $pic = $articles[$i]->picUrl;
                $title = $articles[$i]->title;
            } else {
                $url = $articles[$i]['url'];
                $pic = $articles[$i]['picurl'];
                $title = $articles[$i]['title'];
            }
            $html.='<li>';
            $html.='<div class="thubmtitle"><a href="'.urldecode($url).'" target="_blank">'.urldecode($title).'</a></div>';
            $html.='<div class="thubmimg">';
            $html.='<a href="'.urldecode($url).'" target="_blank"><img src="'.urldecode($pic).'" /></a>';
            $html.='</div>';
            $html.='</li>';
        }
        $html.=' </ul>';
        $html.=' </div>';
        return $html;
    }
    public static function sendNewsByToken($accessToken, $toUser, $articles) {
        $msg["touser"] = $toUser;
        $msg["msgtype"] = message_type_news;
        $newData = array();
        $newDatak = array();
        foreach( $articles as $key => $value ) {
            foreach( $value as $k => $val ){
                $newDatak[$k] = urlencode($val);
            }
            $newData[$key] = $newDatak;
        }
        $msgContent["articles"] = $newData;
        $msg["news"] = $msgContent;
// 		Log::write('news content' . json_encode($msg));
        $msg = urldecode(json_encode($msg));
        $url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $accessToken;
        // 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
        // 		Log::write($result);
        $result = json_decode($result);
        return $result;
    }
    public static function sendTpl($toUser, $tplId, $url, $topColor, $data, $printErr = TRUE,$cid=null) {
        $accessToken = WeixinApi::getAccessToken($printErr,$cid);
        if (!$accessToken) {
            return;
        }
        $msg["touser"] = $toUser;
        $msg["template_id"] = $tplId;
        $msg["url"] = $url;
        $msg["topcolor"] = $topColor;
        $msg["data"] = $data;
        // 		Log::write('news content' . json_encode($msg));
        $msg = urldecode(json_encode($msg));
        $url='https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $accessToken;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        $error = curl_errno($ch);
        curl_close($ch);
        Log::write("模板消息结果:". $result."--".$error);
        $result = json_decode($result);
        return $result;
    }
	
    // 获取卡券列表
    public static function getticList($offset,$count){
        $accessToken = WeixinApi::getAccessToken($printErr);
        if (!$accessToken) {
            return;
        }
        $msg["offset"] = $offset;
        $msg["count"] = $count;
        $msg = urldecode(json_encode($msg));
        $url = 'https://api.weixin.qq.com/card/batchget?access_token='.$accessToken;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
        Log::write("卡券列表结果为:". $result);
        $result = json_decode($result);
        return $result;
    }

    /**
     * 获得公众号配置信息
     *
     * @param null $cid
     * @param null $mId
     * @return mixed
     * LLyeap_wx_customer修改
     */
    public static function getCustomer($cid = null, $mediaId = 0)
    {
        $retVal = Session::init();
        $cid ? $customerId = $cid : $customerId = Session::$user['customerId']; // 这个值不必考虑有没有, 因为肯定会有
        Session::switchCustomer(0);

        $IndMediaInfo_Model = D('ind_media_info');
        if ($mediaId > 0) { // 如果拿到了$mediaId, 则通过id来筛选
            $where_info = ['imi.cid' => $customerId, 'imi.id' => $mediaId];
        } else {        // 如果没有$mediaId, 则拿这个cid下默认的账号, 即default = 1的, 只有一个
            $where_info = ['imi.cid' => $customerId, 'imi.isDefault' => 1];
        }

        $result = $IndMediaInfo_Model->alias('imi')
                ->join('wx_customer_weixin_profile cwp ON cwp.mediaId = imi.id')
                ->field('imi.*, cwp.grantStatus,cwp.nick_name')
                ->where($where_info)
                ->find();
        Session::switchCustomer($customerId);
        if($result == null){
            Log::write('customer is null:'.$IndMediaInfo_Model->getLastSql());
        }
        /***** LLyeap_delete *****/
//        Session::switchCustomer(0);
//        $Customer = D("Customer");
//        $map['a.id'] = $customerId;
//        $result1 = $Customer->alias("a")
//            ->join("wx_customer_weixin_profile b on a.id=b.cid")
//            ->field("a.*,b.grantStatus")
//            ->where($map)->find();
//        Session::switchCustomer($customerId);
        /*****  *****/

        return $result;
    }

    private static function getUser($fromUserName) {
        $UserModel = D("user");
        $map['userName'] = $fromUserName;
        $result = $UserModel->where($map)->find();
        return $result;
    }
    private function getOauthByCode($appid, $appsecret, $code) {
        $url= "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$appsecret&code=$code&grant_type=authorization_code";
 		$ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $access = curl_exec($ch) ;
        curl_close($ch);
 		//Log::write($access);
        $access = json_decode($access);
        if (isset($access->errcode) && $access->errcode != 0) {
            Log::write('oauth error:' . $access->errmsg . $access->errcode);
// 			Output::instance()->resultCode(code_access_expired, $access->errmsg);
            return;
        }
        // 过期时间减去一分钟
        $expiration = time() + ((int)$access->expires_in - 60);
        //self::setUserOauthToken($access->openid, $access->access_token, $expiration, $access->refresh_token);
        $access->expiration = $expiration;
        return $access;
    }
    private function getOauthByRefreshToken($appid, $refreshToken) {
        $url= "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=$appid&grant_type=refresh_token&refresh_token=$refreshToken";
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $access = curl_exec($ch) ;
        curl_close($ch);
 		Log::write($access);
        $access = json_decode($access);
        if (isset($access->errcode) && $access->errcode != 0) {
            Output::instance()->resultCode(code_access_expired, NULL, $access->errcode);
            return;
        }
        // 过期时间减去一分钟
        $expiration = time() + ((int)$access->expires_in - 60);
        $access->expiration = $expiration;
//		self::setUserOauthToken($access->openid, $access->access_token, $expiration, $access->refresh_token);
        return $access;
    }
    /*
     * printErr是否输出错误
     */
    public static function getUserInfo($openId, $printErr = false) {
        $accessToken = WeixinApi::getAccessToken($printErr);
        if (!isset($accessToken)) {
            return;
        }
        $result = WeixinApi::getUserInfoByToken($openId, $accessToken, $printErr);
        return $result;
    }
    public static function getUserInfoByToken($openId, $accessToken, $printErr = false) {
        $url='https://api.weixin.qq.com/cgi-bin/user/info?access_token=' . $accessToken.'&openid='.$openId.'&lang=zh_CN';
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $result = curl_exec($ch) ;
        curl_close($ch);
        Log::write("用户信息   ".$result);
        $userInfo = json_decode($result);
        if (isset($userInfo->errcode) && $userInfo->errcode != 0) {
            Log::write('user info error:' . $userInfo->errmsg);
            if ($printErr) {
                Output::instance()->resultCode(code_userinfo_api_auth, NULL, $userInfo->errcode);
            }
            return;
        }
        if ($userInfo->subscribe == 0) {
            return;
        }
        return $userInfo;
    }

    /**
     * 这里是customer信息修改保存的操作
     *
     * @param      $token
     * @param      $expiration
     * @param      $refreshToken
     * @param null $from
     * LLyeap_wx_customer修改
     */
    private static function setCustomerToken($token, $expiration, $refreshToken, $from = null, $mediaId = 0)
    {
        $customerId = Session::$user['customerId'];
        Session::switchCustomer(0);
        $IndMediaInfo_Model = D('ind_media_info');
        if ($mediaId > 0) { // 如果拿到了$mediaId, 则通过id来筛选
            $where_info = ['cid' => $customerId, 'id' => $mediaId];
        } else {        // 如果没有$mediaId, 则拿这个cid下默认的账号, 即default = 1的, 只有一个
            $where_info = ['cid' => $customerId, 'isDefault' => 1];
        }

        if ($from) {
            $data['wxAppAccessToken'] = $token;
            $data['wxAppAccessExpiration'] = $expiration;
        } else {
            $data['accessToken'] = $token;
            $data['accessExpiration'] = $expiration;
            $data['refreshToken'] = $refreshToken;
        }
        $IndMediaInfo_Model->where($where_info)->save($data);
\Log::write('lilei_setCustomerToken_' . $IndMediaInfo_Model->getLastSql());

        /***** LLyeap_delete *****/
//        $Customer = D("Customer");
//        $map['id'] = $customerId;
//        if ($from) {
//            $data['wxAppAccessToken'] = $token;
//            $data['wxAppAccessExpiration'] = $expiration;
//        } else {
//            $data['accessToken'] = $token;
//            $data['accessExpiration'] = $expiration;
//            $data['refreshToken'] = $refreshToken;
//        }
//        $Customer->where($map)->save($data);
        /*****  *****/

        Session::switchCustomer($customerId);
    }

    public static function setUserOauthToken($fromUserName, $token, $expiration, $refreshToken) {
        $customerId = Session::$user['customerId'];
        $User = D("user");
        $map['userName'] = $fromUserName;
        $data['openid']=$fromUserName;
        $data['oauthAccessToken'] = $token;
        $data['oauthAccessExpiration'] = $expiration;
        $data['oauthRefreshToken'] = $refreshToken;
        $data['lastTime'] = date("Y-m-d H:i:s");
        $result= $User->where($map)->find();
        if($result && count ($result)  > 0){
            $User->where($map)->save($data);
        } else {
            $data['userName']=$fromUserName;
            $data['status']=USER_STATUS_SHARE_SUBSCRIBE;
            $data['profileUrl']=DEFAULT_PROFILE_URL;
            $data['subscribeTime']=date("Y-m-d H:i:s");
            $data['isNew'] = 1;
            $id = $User->add($data);
            $pointData = ['uId' => $id];
            R('call/newUserPoint', [$pointData]);

        }
    }

    //ihziluoh添加高级群发
    /*$touser 群发多用户
     * $mpnews 用于设定即将发送的图文消息（固定不需要传参）
     * $media_id 用于群发的图文消息的media_id
     * $msgtype 群发的消息类型，图文消息为mpnews，文本消息为text，语音为voice，音乐为music，图片为image，视频为video
     * $title 消息的标题
     * $description 	消息的描述
     * $thumb_media_id 视频缩略图的媒体ID
     * $text 文本消息内容
    */
    public static function mass($touser, $media_id='' ,$msgtype, $title='', $description='', $thumb_media_id='',$text='',$mediaId) {
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $msg['touser'] = explode(",",$touser);
        $msg['msgtype'] = $msgtype;
        $msg['send_ignore_reprint'] = 1;
        $title=urlencode ($title);
        $description=urlencode ($description);
        $text=urlencode ($text);
        switch ($msgtype) {
            case mpnews:
                //图文
                $msg['mpnews']['media_id'] = $media_id;
                $msg['title'] = $title;
                $msg['description'] = $description;
                //$msg=json_encode($msg);
                break;
            case text:
                //文本
                $msg['text']['content'] =$text;
                $msg['title'] = $title;
                $msg['description'] = $description;
                //$msg=json_encode($msg);
                break;
            case voice:
                $msg['voice']['media_id'] = $media_id;
                $msg['title'] = $title;
                $msg['description'] = $description;
                //语音
                break;
            case image:
                $msg['image']['media_id'] = $media_id;
                $msg['title'] = $title;
                $msg['description'] = $description;
                //图片
                break;
            case video:
                $msg['video']['media_id'] = $media_id;
                $msg['video']['title'] = $title;
                $msg['description']['title'] = $description;
                //视频
                break;
            default:
                throw_exception('不存在的群发类型');
        }
        //Log::write('mass text json_encode' . urldecode (json_encode($msg)));
        $msg = urldecode(json_encode($msg));
        $url='https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=' . $access_token;
        // 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
//        $result = json_decode($result);
//        if (isset($result->errcode) && $result->errcode != 0) {
//            Log::write('mass error:' . $result->errmsg);
//            Output::instance()->resultCode(code_mass_fail, NULL, $result->errcode);
//            return false;
//        }
        return $result;
    }

    /**
     * 删除群发消息
     * @param $msg_id
     * @param string $article_idx
     * @param int $mediaId /自媒体id
     * @return bool|mixed
     */
    public static function delmass($msg_id,$article_idx='',$mediaId=0) {
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $msg['msg_id'] = $msg_id;
        if(!empty($article_idx)){
            $msg['article_idx'] = $article_idx;
        }
        $msg = json_encode($msg);
        $url='https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=' . $access_token;
        Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
        Log::write('delmass:' . $result);
        $result = json_decode($result,true);
        if (isset($result->errcode) && $result->errcode != 0) {
            Log::write('mass error:' . $result->errmsg);
            Output::instance()->resultCode(code_mass_fail, NULL, $result->errcode);
            return false;
        }
        return $result;
    }
    //ihziluoh添加上传素材
    public static function uploadMaterial($articles) {
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        Log::write('uploadMaterial');
        $url='https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=' . $access_token;

        // 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $articles);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
 		Log::write($result);
        $result = json_decode($result);
        if (isset($result->errcode) && $result->errcode != 0) {
            Log::write('mass error:' . $result->errmsg);
            Output::instance()->resultCode(code_mass_fail, NULL, $result->errcode);
            return false;
        }
        return $result;
    }

    /**
     * peng
     * @param $articles
     * @return bool|mixed
     */
    public static function newUploadMaterial($articles,$mediaId){
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token='.$access_token;
        $data = json_encode($articles,JSON_UNESCAPED_UNICODE );
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = curl_exec($ch);
        curl_close($ch);
        //将返回的数据转换成数组
        $result=json_decode($data,true);
        return $result;
    }
    //ihziluoh添加多媒体上传（微信官方文档以更新，添加多媒体请调newUploadmedia接口）
    public static function uploadMedia($type,$filepath) {
// 		log::write("enter the weixinapi uploadmedia".$type.$filepath);
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $fileUrl = C('SERVER_HOST');
        $str = ABSPATH;
        // 锐步项目地址特殊，做处理去掉SERVER_HOST中最后一个/的内容
        if (strstr($fileUrl, 'wechain')) {
            $fileUrl = str_replace('/wx/', '/', $fileUrl);
            $str = str_replace('/wx/', '/', $str);
        }
// 		Log::write('url '. $url);
// 		Log::write('str ===========' . $str);
// 		Log::write('file======== '. $filepath);
// 		$str = str_replace("wx_api\Lib\weixin", "", $str);
        $filepath = str_replace($fileUrl, $str, $filepath);
        if (strpos($filepath , '/') === 0) {
            $filepath = substr($filepath, 1);
        }
// 		Log::write('uploadMedia file========'.$filepath);
// 		Log::write('http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=' . $access_token .'&type='.$type);
        $url='https://api.weixin.qq.com/cgi-bin/media/upload?access_token=' . $access_token .'&type='.$type;
        $fields['media'] = "@".$filepath;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        Log::write('uploadMedia result:' . $result);
        $result = json_decode($result);
        if (isset($result->errcode) && $result->errcode != 0) {
            Log::write('uploadMedia error:' . $result->errmsg);
            Output::instance()->resultCode(code_mass_upload_media, NULL, $result->errcode);
            return false;
        }
        return $result;
    }
    //新添加多媒体上传
    public static function newUploadmedia($type,$filepath,$mediaId){
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
// 		Log::write('uploadMedia file========'.$filepath);
// 		Log::write('http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=' . $access_token .'&type='.$type);
        $url='https://api.weixin.qq.com/cgi-bin/media/upload?access_token=' . $access_token .'&type='.$type;
        $fields['media'] = "@".$filepath;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        Log::write('uploadMedia result:' . $result);
        $result = json_decode($result);
        if (isset($result->errcode) && $result->errcode != 0) {
            Log::write('uploadMedia error:' . $result->errmsg);
            Output::instance()->resultCode(code_mass_upload_media, NULL, $result->errcode);
            return false;
        }else{
            return $result;
        }
    }


    public static function getUserList($nextOpenId = '') {
        $accessToken = WeixinApi::getAccessToken();
        if (!$accessToken) {
            return;
        }
        //获取所有用户openid
        $url= "https://api.weixin.qq.com/cgi-bin/user/get?access_token=$accessToken&next_openid={$nextOpenId}";
// 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        $result = curl_exec($ch);
        curl_close($ch);
//  	Log::write($result);
 		$result = json_decode($result);
 		if (isset($result->errcode) && $result->errcode != 0) {
 			Output::instance()->resultCode(code_user_list_error, NULL,  $result->errcode);
 			return;
 		} else {
 			return $result;
 		}
    }
    public static function downloadMedia1($mediaId) {
        //$accessToken = WeixinApi::getAccessToken();
        $accessToken="9SN5V4k_m46BRyBWIYufUMlGvB3ILyCxXIQc6V3eKa_v2YrcpxHykLbroIpLMPSqkJrYP09IFSoyLJYYrMNZLGQgR4femBG0ElSp2jwVm28";
        if (!$accessToken) {
            return;
        }
        $url = 'http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=9SN5V4k_m46BRyBWIYufUMlGvB3ILyCxXIQc6V3eKa_v2YrcpxHykLbroIpLMPSqkJrYP09IFSoyLJYYrMNZLGQgR4femBG0ElSp2jwVm28&media_id=' . $mediaId;
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_NOBODY, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $package = curl_exec($ch);
        $httpinfo = curl_getinfo($ch);
        curl_close($ch);
        $extension = '.jpg';
        $filename = md5 ( $mediaId );
        $lp = LOCAL_PIC_PATH . '\\' . $filename . $extension;
        $fp = fopen($lp, 'w');
        if (!$fp) {
            fwrite($fp, $package);
            fclose($fp);
        } else {
            Log::write('[downloadMedia fopen failed] ' . $lp);
            return;
        }
        Log::write("downloadMedia".$lp);
        return $lp;
    }
    public static function downLoadMedia($media_id,$extension = '.jpg') {
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $filename = md5 ( $media_id );
        $lp = LOCAL_PIC_PATH . $filename . $extension;
        $url='https://api.weixin.qq.com/cgi-bin/media/get?access_token=' . $access_token .'&media_id='.$media_id;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'get');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = curl_exec($ch) ;
        $httpinfo =curl_getinfo($ch);
        $fp = fopen($lp,"w");
        if ($fp) {
        	fwrite($fp,$data);
        }
        fclose($fp);
        return $lp;
    }
    //发送客服消息
    public static function sendServiceMsg($touser, $msgtype, $text='',$articles=null,$media_id=null) {
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $msg['touser'] = $touser;
        $msg['msgtype'] = $msgtype;
        $text=urlencode ($text);
        switch ($msgtype) {
            case "text":
                //文本
                $msg['text']['content'] =$text;
                //$msg=json_encode($msg);
                break;
            case "news":
                $msg['news']["articles"]=$articles;
                break;
            case "image":
                $msg['image']['media_id']=$media_id;
                break;
            case "voice":
                $msg['voice']['media_id']=$media_id;
                break;
            case "video":
                $msg['video']['media_id']=$media_id;
                $msg['video']['thumb_media_id']="";
                $msg['video']['title']="";
                $msg['video']['description']="";
                break;
            case "music":
                $msg['music']['title']="";
                $msg['music']['description']="";
                $msg['music']['musicurl']=$text;
                $msg['music']['hqmusicurl']=$text;
                $msg['music']['thumb_media_id']=$media_id;
                break;
            default:
                throw_exception('不存在的消息类型');
        }
        //Log::write('mass text json_encode' . urldecode (json_encode($msg)));
        $msg = urldecode(json_encode($msg));
        $url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $access_token;
        // 		Log::write($url);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
        $result = curl_exec($ch);
        $errno = curl_errno($ch);
        curl_close($ch);
        $result = json_decode($result);
        Log::write("客服消息curl错误码  ".$errno);
        if (isset($result->errcode) && $result->errcode != 0) {
            Log::write('mass error:' . $result->errmsg);
        }
        return $result;
    }
    //微信发送红包
    //WeixinApi::sendRedEnvelopeByOpenId('发送红包人名称','用户openid', 金额,'祝福语');
    public static function sendRedEnvelopeByOpenId($send_name,$openid,$amount,$wishing,$printErr = false,$partnerkey='',$mch_id='',$wxappid='',$nick_name='密友圈',$total_num=1,$act_name='活动名称',$remark='备注',$logo_imgurl='https://wx.gtimg.com/mch/img/ico-logo.png',$share_content='分享文案',$share_url='',$share_imgurl='https://wx.gtimg.com/mch/img/ico-logo.png',$sub_mch_id=null,$merchantMode=0) {
        if($wxappid==''){
            $wxappid=C("PLANT_APPID");
        }
        if($mch_id==''){
            $mch_id=C("PLANT_MCHID");
        }
        if($partnerkey==''){
            $partnerkey=C("PLANT_PARTNERKEY");
        }
        $str = '1234567890abcdefghijklmnopqrstuvwxyz';
        for($i=0;$i<30;$i++){
            $j=rand(0,35);
            $t1 .= $str[$j];
        }
        $arr['nonce_str']=$t1;
       	$amount=ceil($amount*100);
        $arr['mch_id']=$mch_id;
        $arr['mch_billno']= $arr['mch_id'].date('YmdHis').rand(1000,9999);
        if($merchantMode){
            $arr['sub_mch_id']=$sub_mch_id;
        }
        $arr['wxappid']=$wxappid;
//	    $arr['nick_name']=$nick_name;
        $arr['send_name']=$send_name;
        $arr['re_openid']=$openid;
        $arr['total_amount']=$amount;
//	    $arr['min_value']=$amount;
//	    $arr['max_value']=$amount;
        $arr['total_num']=$total_num;
        $wishing = empty($wishing)? '恭喜发财，大吉大利。' : $wishing;
        $arr['wishing']=$wishing;
        $arr['client_ip']=get_client_ip();
        $arr['act_name']=$act_name;
        $arr['remark']=$remark;
//	    $arr['logo_imgurl']=$logo_imgurl;
//	    $arr['share_content']=$share_content;
//	    $arr['share_url']=$share_url;
//	    $arr['share_imgurl']=$share_imgurl;
        $wxPayHelper = new WxPayHelper();
        $xmls=$wxPayHelper->getSignValBykeyArr($partnerkey,$arr);
       // $arr['sign']=$pkg;
        //$xmls=WeixinApi::arrayToXml($arr);
       // log::write('提现传递参数'.$xmls);
        $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';
        //$vars=$xmls;
        $second=30;
        $aHeader=array();
        $ch = curl_init();
        //超时时间
        curl_setopt($ch,CURLOPT_TIMEOUT,$second);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
        //这里设置代理，如果有的话
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
        //cert 与 key 分别属于两个.pem文件
        curl_setopt($ch,CURLOPT_SSLCERT,WXPAY_CERT_PATH.$mch_id.'cert.pem');
 		curl_setopt($ch,CURLOPT_SSLKEY,WXPAY_CERT_PATH.$mch_id.'.pem');
 		//curl_setopt($ch,CURLOPT_CAINFO,WXPAY_CERT_PATH.'rootca.pem');
        if( count($aHeader) >= 1 ){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }
        curl_setopt($ch,CURLOPT_POST, 1);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$xmls);
        $data = curl_exec($ch);
        log::write('提现返回结果'.$data);
        $responseObj = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
        if($data){
            $arr['result_code']="$responseObj->result_code";
            $arr['return_msg']="$responseObj->return_msg";
            MiYouQuanAction::addMiRedenvelopeLog($arr);
        }
        if ($responseObj->result_code == 'SUCCESS') {
           // WeixinApi::saveTextMessage($toUser, $content);
            if ($printErr) {
                Output::instance()->resultCode();
                return true;
            } else {
                return true;
            }
        } else {
            $msg = $responseObj->return_msg;
            $msg = json_decode(json_encode($msg),true);
            if($responseObj->result_code=='NOTENOUGH'){
                $customerId = Session::$user['customerId'];
                Session::switchCustomer(0);
                $customerModule = M("customer_user");
                Session::switchCustomer($customerId);
                $customerInfo = $customerModule->where("customerId=$customerId and agent='business'")->find();
                SendMail($customerInfo['email'],'密友圈系统提醒','您的密友圈账号在发送晒单红包时出现错误，原因是：'.$msg[0],null,null);
            }
           if ($printErr) {
                Output::instance()->resultCode(1, $msg[0]);
                return true;
            } else {
                return false;
            }
        }
    }
    //微信企业付款转账
    //WeixinApi::transferAccountsByOpenId('用户openid', 金额,'祝福语');
    public static function transferAccountsByOpenId($openid,$amount,$desc,$printErr = false,$partnerkey='',$mch_id='',$wxappid='',$check_name='NO_CHECK',$re_user_name='',$sub_mch_id='',$device_info='') {
        log::write("进入transferAccountsByOpenId方法结果");
        if($wxappid ==''){
            $wxappid=C("PLANT_APPID");
        }
        if($mch_id ==''){
            $mch_id=C("PLANT_MCHID");
        }
        if($partnerkey ==''){
            $partnerkey=C("PLANT_PARTNERKEY");
        }
        $arr['sub_mch_id']=$sub_mch_id;
        $arr['device_info']=$device_info;
        $str = '1234567890abcdefghijklmnopqrstuvwxyz';
        for($i=0;$i<30;$i++){
            $j=rand(0,35);
            $t1.= $str[$j];
        }
        $arr['mchid']=$mch_id;
        $arr['mch_appid']=$wxappid;
        $arr['nonce_str']=$t1;
        //订单号
        $arr['partner_trade_no']=$arr['mchid'].date('YmdHis').rand(1000,9999);
        $arr['openid']=$openid;
        $arr['check_name']='NO_CHECK';
        $arr['re_user_name']='';
        $amount=round($amount*100,0);
        $arr['amount']=$amount;
        $arr['desc']=$desc;
        $arr['spbill_create_ip']=get_client_ip();
        $wxPayHelper = new WxPayHelper();
        $xmls=$wxPayHelper->getSignValBykeyArr($partnerkey,$arr);
        //log::write('提现传递参数'.$xmls);
        // var_dump($xmls);
        $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
        //$vars=$xmls;
        $second=30;
        $aHeader=array();
        $ch = curl_init();
        //超时时间
        curl_setopt($ch,CURLOPT_TIMEOUT,$second);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
        //这里设置代理，如果有的话
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
        //cert 与 key 分别属于两个.pem文件
        curl_setopt($ch,CURLOPT_SSLCERT,WXPAY_CERT_PATH.$mch_id.'cert.pem');
        curl_setopt($ch,CURLOPT_SSLKEY,WXPAY_CERT_PATH.$mch_id.'.pem');
       // curl_setopt($ch,CURLOPT_CAINFO,WXPAY_CERT_PATH.'rootca.pem');
        if( count($aHeader) >= 1 ){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }
        curl_setopt($ch,CURLOPT_POST, 1);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$xmls);
        $data = curl_exec($ch);
        Log::write('提现返回结果'.$data);
        $responseObj = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($responseObj->return_code == 'SUCCESS') {
            // WeixinApi::saveTextMessage($toUser, $content);
            $arr['return_code']="$responseObj->return_code";
            $arr['return_msg']="$responseObj->return_msg";
            $arr['mch_appid']="$responseObj->mch_appid";
            $arr['mchid']="$responseObj->mchid";
            $arr['device_info']="$responseObj->device_info";
            $arr['nonce_str']="$responseObj->nonce_str";
            $arr['sign']="$responseObj->sign";
                $arr['result_code']="$responseObj->result_code";
                $arr['err_code']="$responseObj->err_code";
                    $arr['err_code_des']="$responseObj->err_code_des";
                        if($responseObj->result_code == 'SUCCESS'){
                        $arr['partner_trade_no']="$responseObj->partner_trade_no";
                        $arr['payment_no']="$responseObj->payment_no";
                            $arr['payment_time']="$responseObj->payment_time";
            }else{
                            return false;
                        }
            MiYouQuanAction::addTransferAccountsLog($arr);
            if ($printErr) {
                Output::instance()->resultCode();
                return true;
            } else {
                return true;
            }
        } else {
            $arr['return_code']="$responseObj->return_code";
            $arr['return_msg']="$responseObj->return_msg";
            MiYouQuanAction::addTransferAccountsLog($arr);
            if ($printErr) {
                Output::instance()->resultCode(code_user_msg_send_fail, NULL, "$responseObj->return_msg");
                return true;
            } else {
                return false;
            }
        }
    }
    /**
     * [uploadImageToWeixin 上传图片到微信服务器，用于图文素材不支持外链的情况]
     * @param  [type] $filename [description]
     * @return [type]           [description]
     */
    public static function uploadImage($fileInfo,$mediaId) {
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=' . $access_token;
        $filename=$fileInfo["path"];
        $fields['media'] = "@".$filename;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //长链接转短链接
    public static function long2short($long_url) {
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/shorturl?access_token=' . $access_token;
        $fields['action'] = "long2short";
        $fields['long_url'] = $long_url;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //查询所有用户分组
    public static function getUserGroup(){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/groups/get?access_token=' . $access_token;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //创建用户分组
    public static function createUserGroup($groupName){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/groups/create?access_token='.$access_token;
        $fields['group']['name'] = $groupName;
        $fields = urldecode(json_encode($fields,JSON_UNESCAPED_UNICODE));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //修改分组名
    public static function setUserGroupName($groupId,$groupName){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/groups/update?access_token='.$access_token;
        $fields['group']['id'] = $groupId;
        $fields['group']['name'] = $groupName;
        $fields = urldecode(json_encode($fields,JSON_UNESCAPED_UNICODE));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //删除分组 注意本接口是删除一个用户分组，删除分组后，所有该分组内的用户自动进入默认分组
    public static function deletedUserGroup($groupId){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/groups/delete?access_token='.$access_token;
        $fields['group']['id'] = $groupId;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //移动用户分组
    public static function removeUserToGroup($openid,$to_groupid){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token='.$access_token;
        $fields['openid']=$openid;
        $fields['to_groupid'] = $to_groupid;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //批量移动用户分组
    public static function removeUsersToGroup($openid_list,$to_groupid){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/groups/members/batchupdate?access_token='.$access_token;
        $fields['openid_list']=$openid_list;
        $fields['to_groupid'] = $to_groupid;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }

    /**
     * 查询用户标签
     * @param int $mediaId 自媒体id
     * @return bool|mixed
     */
    public static function getUserTag($mediaId = 0){
        $access_token = WeixinApi::getAccessToken(true, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/tags/get?access_token=' . $access_token;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }

    /**
     * 获取此标签下的所有用户
     * @param $tagId /标签id
     * @return bool|mixed
     */
    public static function getGroupUserInfo($tagId){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }

        $url='https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=' . $access_token;
        $fields['tagid'] = $tagId;
        $fields['next_openid'] = '';
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }

    /**
     * //创建用户标签
     * @param $tagName /分组名称
     * @param $mediaId /自媒体id
     * @return bool|mixed
     */
    public static function createUserTag($tagName, $mediaId){
        $access_token = WeixinApi::getAccessToken(true, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/tags/create?access_token='.$access_token;
        $fields['tag']['name'] = $tagName;
        $fields = urldecode(json_encode($fields,JSON_UNESCAPED_UNICODE));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //修改标签名
    public static function setUserTagName($tagId,$tagName){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/tags/update?access_token='.$access_token;
        $fields['tag']['id'] = $tagId;
        $fields['tag']['name'] = $tagName;
        $fields = urldecode(json_encode($fields,JSON_UNESCAPED_UNICODE));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //删除标签 请注意，当某个标签下的粉丝超过10w时，后台不可直接删除标签。此时，开发者可以对该标签下的openid列表，先进行取消标签的操作，直到粉丝数不超过10w后，才可直接删除该标签。
    /**
     * //删除标签
     * @param $tagId
     * @param $mediaId /自媒体id
     * @return bool|mixed
     */
    public static function deletedUserTag($tagId,$mediaId){
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/tags/delete?access_token='.$access_token;
        $fields['tag']['id'] = $tagId;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }

    /**
     * 批量用户打标签
     * @param $openid_list /用户openid
     * @param $tagid /分组id
     * @param $mediaId /自媒体id
     * @return bool|mixed
     */
    public static function setUsersTag($openid_list,$tagid, $mediaId = 0){
        $access_token = WeixinApi::getAccessToken(true, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token='.$access_token;
        $fields['openid_list']=$openid_list;
        $fields['tagid'] = $tagid;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }

    /**
     * 批量用户取消标签
     * @param $openid_list /用户openid
     * @param $tagid /分组id
     * @param $mediaId /自媒体id
     * @return bool|mixed
     */
    public static function deletedUsersTag($openid_list,$tagid,$mediaId=0){
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token='.$access_token;
        $fields['openid_list']=$openid_list;
        $fields['tagid'] = $tagid;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //查询用户所有标签
    public static function getUserAllTags($openid){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/tags/getidlist?access_token='.$access_token;
        $fields['openid']=$openid;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }

    /**
     * 创建个性化菜单
     *
     * @param     $menu
     * @param int $mediaId
     * @return bool|mixed
     */
    public static function addconditional($menu, $mediaId = 0)
    {
        $access_token = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=' . $access_token;
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $menu);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    /**
     * 删除个性化菜单
     *
     * @param     $menuid
     * @param int $mediaId
     * @return bool|mixed
     */
    public static function delconditional($menuid, $mediaId = 0){
        $access_token = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token='.$access_token;
        $fields['menuid']=$menuid;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //获取素材数量
    public static function get_materialcount(){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token='.$access_token;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //删除素材
    public static function del_material($media_id, $mediaId = 0){
        $access_token = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/material/del_material?access_token='.$access_token;
        $fields['media_id']=$media_id;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //添加图文永久素材
    public static function add_news($articles, $mediaId){
        $access_token = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/material/add_news?access_token='.$access_token;
        /*$data['articles']=array();
        array_push($data['articles'],$articles);*/
        $data = $articles;
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    //添加永久素材
    public static function add_material($type,$file_info,$mediaId){
        $access_token = WeixinApi::getAccessToken(TRUE, null, null, $mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/material/add_material?access_token='.$access_token.'&type='.$type;
        $real_path="{$file_info['filename']}";
        if ($type == "video") {
            unset($file_info['filename']);
            unset($file_info['content-type']);
            unset($file_info['filelength']);
            $data = array("media" => "@{$real_path}", 'description' => urldecode(json_encode($file_info, JSON_UNESCAPED_UNICODE)));
        } else {
            $data = array("media" => "@{$real_path}", 'form-data' => $file_info);
        }
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    //获得素材列表
    public static function batchget_material($type,$offset,$count){
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token='.$access_token;
        $fields['type']=$type;
        $fields['offset']=$offset;
        $fields['count']=$count;
        $fields = urldecode(json_encode($fields));
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }
    //获得多媒体临时素材
    public static function downWeixinMedia($media_id,$filename) {
        $access_token = WeixinApi::getAccessToken();
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/media/get?access_token=' . $access_token .'&media_id='.$media_id;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        $fp = fopen($filename,"w");
        if ($fp) {
            fwrite($fp,$result);
        }
        fclose($fp);
        return $filename;
    }
    //获得小程序二维码
    public static function createwxaqrcode($page,$fileName,$width=null,$printErr = TRUE,$cid=null){
        $accessToken = WeixinApi::getAccessToken($printErr,$cid,"app");
        if (!$accessToken) {
            return;
        }
        $msg['path']=$page;
        $width?$msg['width']=$width:"";
        $msg = json_encode($msg);
        $url='https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=' . $accessToken;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
        $fp = fopen($fileName,'wb');
        fwrite($fp,$result);
        fclose($fp);
        $result = R("Upload/uploadLocalFileToOss",array($fileName,$fileName));
        return $result;
    }
    //获取预览接口
    public static function sendPreview($touser,$media_id,$msgtype,$mediaId){
        //获取accessToken
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $msg['towxname'] = $touser;
        $msg['mpnews']['media_id'] = $media_id;
        $msg['msgtype'] = $msgtype;
        $url='https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token='.$access_token;

        $data = json_encode($msg);
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $re= curl_exec($ch);
        curl_close($ch);
        //将返回的数据转换成数组
        $result=json_decode($re,true);
        return $result;
    }

    /**
     * 根据标签进行群发
     * @param $is_to_all  判断发送的类型(true(全部)false(分组))
     * @param $tag_id     分组id
     * @param $media_id   图文微信端的media_id
     * @param $msgType    群发类型
     * @param $mediaId    自媒体账号id
     * @param $send_ignore_reprint    是否强制转载
     */
    public static function sendAll($is_to_all,$tag_id,$media_id,$msgType,$mediaId, $send_ignore_reprint=0){
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token='.$access_token;
        $msg['filter']['is_to_all']=$is_to_all;
        if($is_to_all==false){
            $msg['filter']['tag_id']=$tag_id;
        }
        switch ($msgType) {
            case mpnews:
                //图文
                $msg['mpnews']['media_id'] = $media_id;
                $msg['send_ignore_reprint'] = $send_ignore_reprint;
                //$msg=json_encode($msg);
                break;
            case text:
                //文本
                $msg['text']['content'] =$media_id;
                break;
            case voice:
                $msg['voice']['media_id'] = $media_id;
                //语音
                break;
            case image:
                $msg['image']['media_id'] = $media_id;
                //图片
                break;
            case video:
                $msg['video']['media_id'] = $media_id;
                //视频
                break;
            default:
                throw_exception('不存在的群发类型');
        }
        $msg['msgtype'] = $msgType;

        $data = json_encode($msg);
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置curl允许执行的最长秒数为5
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    public static function getTemplate($mediaId){
        $access_token = WeixinApi::getAccessToken(true,null,null,$mediaId);
        if (!isset($access_token)) {
            return false;
        }
        $url='https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=' . $access_token;
        $ch = curl_init($url) ;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch) ;
        curl_close($ch);
        return $result;
    }

}